<?php

namespace app\index\controller;

use app\common\model\ChatList;
use app\index\BaseController;
use app\common\model\PrivateMessage;
use app\common\services\PrivateMessage as PrivateMessageService;
use app\common\model\User;
use think\Db;

class MessagesPrivate extends BaseController
{
    /**
     * 获取当前用户总消息条数和已读消息条数
     *
     * @return \think\Response
     */
    public function getPrivateMessageCount()
    {
        $user = getCurrentUser();
        $currentUserId = $user->id;

        $data = PrivateMessage::alias('pm')
            ->where('to_id', $currentUserId)
            ->field([
                'COUNT(*)' => 'received_count',
                'SUM(pm.is_read)' => 'read_count',
            ])
            ->find();

        $data['received_count'] = intval($data['received_count']);
        $data['read_count'] = intval($data['read_count']);

        return json($data);
    }

    /**
     * 获取所有联系人
     *
     * @return \think\Response
     */
    public function getAllContatcs()
    {
        return json(User::where(1)->select());
    }

    /**
     * 翻页获取消息列表
     *
     * @return \think\Response
     * @args page? 页码
     */
    public function fetchChatList()
    {
        $user = getCurrentUser();
        $currentUserId = $user->id;

        $data = $this->getChatListQuery()
            ->where('left_id', $currentUserId)
            ->order('unread_count desc, last_received desc, last_read desc')
            ->paginate(15);

        return json($data);
    }

    /**
     * 获取和某一个人的聊天消息
     *
     * @return \think\Response
     * @args right_id 和谁的聊天消息
     * @args offset? 开始位置
     * @args limit? 获取个数
     */
    public function fetchPrivateMessages($right_id)
    {
        $offset = input('offset', 0);
        $limit = input('limit', 5);
        $offset = intval($offset);
        $limit = intval($limit);

        $user = getCurrentUser();
        $currentUserId = $user->id;

        $total = $this->getPrivateMessagesQuery($currentUserId, $right_id)->count();

        $data = $this->getPrivateMessagesQuery($currentUserId, $right_id)
            ->limit($offset, $limit)
            ->select();

        return json([
            'total' => $total,
            'data' => $data,
        ]);
    }

    public function getChatListQuery()
    {
        // 所有人收信列表
        $receivedChatList = Db::table('private_messages')
            ->field([
                'to_id' => 'left_id',
                'from_id' => 'right_id',
                'COUNT(*)' => 'received_count',
                'SUM(is_read)' => 'read_count',
                '(COUNT(*) - SUM(is_read))' => 'unread_count',
                'MAX(create_at)' => 'last_received',
                'MAX(update_at)' => 'last_read',
            ])
            ->group('to_id, from_id')
            ->buildSql();

        // 所有人发信列表（左右交换后）
        $sentChatList = Db::table('private_messages')
            ->field([
                'from_id' => 'left_id',
                'to_id' => 'right_id',
                '0 as received_count',
                '0 as read_count',
                '0 as unread_count',
                'MAX(create_at)' => 'last_received',
                '0 as last_read',
            ])
            ->group('to_id, from_id')
            ->buildSql();

        // UNION查询
        $union = "($receivedChatList UNION $sentChatList)";

        // 结果集拼接
        $query = Db::table($union . ' as cl')
                ->field([
                    'cl.left_id',
                    'cl.right_id',
                    'SUM(cl.received_count)' => 'received_count',
                    'SUM(cl.read_count)' => 'read_count',
                    'SUM(cl.unread_count)' => 'unread_count',
                    'last_private_message_id(cl.left_id, cl.right_id)' => 'last_message_id',
                    'MAX(cl.last_received)' => 'last_received',
                    'MAX(cl.last_read)' => 'last_read',
                ])
                ->group('left_id, right_id')
                ->model(new ChatList())
                ->setOption('with', ['lastMessage'])
                ->setOption('collection', true);

        return $query;
    }

    public function getPrivateMessagesQuery($leftId, $rightId)
    {
        // 接收到的消息
        $query = PrivateMessage::where('(to_id = :l1 AND from_id = :r1) OR (from_id = :l2 AND to_id = :r2)')
            ->bind([
                'l1' => [$leftId, \PDO::PARAM_INT],
                'r1' => [$rightId, \PDO::PARAM_INT],
                'l2' => [$leftId, \PDO::PARAM_INT],
                'r2' => [$rightId, \PDO::PARAM_INT],
            ])
            ->order('create_at desc');

        return $query;
    }

    /**
     * 按ID获取私信，标记为已读
     *
     * @return \think\Response
     * @args id 私信ID
     */
    public function getPrivateMessages($id)
    {
        $user = getCurrentUser();

        /** @var PrivateMessage $message */
        $message = PrivateMessage::where('id', $id)->find();
        if (!$message) {
            error('私信未找到');
        }

        if ($message->to_id !== $user->id) {
            error('这不是你的私信，无法阅读');
        }

        // 标记未已读
        $message->is_read = true;
        $message->save();
        return json([
            'message' => "消息 $id 已读",
        ]);
    }

    /**
     * 发送私信
     *
     * @return \think\Response
     * @args to_id 接收者用户ID
     * @args content 消息内容
     */
    public function createPrivateMessage(PrivateMessageService $service)
    {
        $this->validateOrError();

        $to_id = input('to_id');
        $content = input('content');

        $user = User::where('id', $to_id)->find();
        if (!$user) {
            error('接收者不存在');
        }
        if (\getCurrentUser()->id === intval($user->id)) {
            error('你不能给自己发消息');
        }

        $service->send($content)->to($user);

        return json([
            'message' => '发送成功',
        ]);
    }

    /**
     * 撤回消息
     *
     * @return \think\Response
     * @args id ID
     */
    public function removePrivateMessage($id)
    {
        /** @var PrivateMessage $message */
        $message = PrivateMessage::where('id', $id)->find();
        if (!$message) {
            error('消息不存在');
        }

        $user = getCurrentUser();
        if ($message->from_id !== $user->id) {
            error('你不是消息发送者，不能撤回消息');
        }

        // 删除消息
        $message->delete();

        return json([
            'message' => '撤回成功',
        ]);
    }
}
